package com.next

import grails.transaction.Transactional
import org.springframework.security.access.annotation.Secured

import java.text.SimpleDateFormat

import static org.springframework.http.HttpStatus.*

@Secured(['ROLE_ADMINISTRATOR', 'ROLE_COMPANY_ADMINISTRATOR', 'ROLE_COMPANY_USER'])
@Transactional(readOnly = true)
class ActivityController
{
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def contactService
    def opportunityService
    def springSecurityService
    def subscribeService

    def index(Integer max)
    {
        def user = User.findByUsername(springSecurityService?.getPrincipal()?.username)
        if (UserRole.findByUserAndRole(user, Role.findByAuthority('ROLE_ADMINISTRATOR')) || UserRole.findByUserAndRole(user, Role.findByAuthority('ROLE_COMPANY_ADMINISTRATOR')))
        {
            def activityList = Activity.findAll("from Activity order by modifiedDate desc", [max: params.max ?: 10, offset: params.offset ?: 0])
            def count = Activity.executeQuery("select count(id) from Activity")
            respond activityList, model: [activityCount: count[0]], view: 'administrator'
        }
        else
        {
            def appointmentList = Activity.findAllByAssignedToAndTypeInList(user, [ActivityType.findByName('Appointment'), ActivityType.findByName('Task')])
            def taskList = Activity.findAllByAssignedToAndType(user, ActivityType.findByName('Task'))
            def myTaskList = Activity.findAllByAssignedToAndStatusInListAndTypeInList(user, ['未执行', '已推迟'], [ActivityType.findByName('Appointment'), ActivityType.findByName('Task')], [sort: "startTime", order: "asc"])
            respond appointmentList, model: [appointmentList: appointmentList, taskList: taskList, myTaskList: myTaskList]
        }

    }

    def taskTime(Integer max)
    {
        def user = User.findByUsername(springSecurityService?.getPrincipal()?.username)
        def taskType = ActivityType.findByName('Task')
        def actualStartTime = params['actualStartTime']
        def actualEndTime = params['actualEndTime']

        def searchClosure = {
            eq('type', taskType)
            eq('status', '已完成')
            if (actualStartTime)
            {
                gt('actualStartTime', actualStartTime)
            }
            if (actualEndTime)
            {
                le('actualEndTime', actualEndTime)
            }
            if (!UserRole.findByUserAndRole(user, Role.findByAuthority('ROLE_ADMINISTRATOR')) && !UserRole.findByUserAndRole(user, Role.findByAuthority('ROLE_COMPANY_ADMINISTRATOR')))
            {
                eq('user', user)
            }
            order 'modifiedDate', "desc"
        }
        def activityCriteria = Activity.createCriteria()
        def activityList = activityCriteria.list(params, searchClosure)
        def activityCount = activityList?.totalCount
        respond activityList, model: [activityList: activityList, activityCount: activityCount, params: params]
    }

    def show(Activity activity)
    {
        def attachmentList = Attachment.findAll("from Attachment where activity.id = ?", [activity.id])
        def noteList = Note.findAll("from Note where activity.id = ?", [activity.id])
        def teamList = ActivityTeam.findAll("from ActivityTeam where activity.id = ?", [activity.id])
        def flexFieldInstanceList = FlexFieldInstance.findAll("from FlexFieldInstance where activity.id = ?", [activity.id])
        def user = User.findByUsername(springSecurityService?.getPrincipal()?.username)
        def displayRating = activity.status == '已完成' && user.id == activity?.user?.id
        def follow = Follow.findByActivityAndUser(activity, user)
        def workflowInstanceList = WorkflowInstance.findAllByActivity(activity)
        respond activity, model: [attachmentList: attachmentList, noteList: noteList, teamList: teamList, flexFieldInstanceList: flexFieldInstanceList, teamName: 'activityTeam', displayRating: displayRating, follow: follow, workflowInstanceList: workflowInstanceList]
    }

    def create()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new Activity(params), model: [user: user]
    }

    def createTask()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new Activity(params), model: [user: user]
    }

    def createAppointment()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        respond new Activity(params), model: [user: user]
    }

    @Transactional
    def save(Activity activity)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (activity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (activity.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond activity.errors, model: [user: user], view: 'create'
            return
        }

        def existList = Activity.findAll("from Activity where assignedTo.id = :assignedTo and status in :statusList and :startTime between startTime and endTime", [assignedTo: activity?.assignedTo?.id, statusList: ['未执行', '已推迟'], startTime: activity?.startTime])
        if (existList)
        {
            flash.message = message(code: 'activity.startTime.exist.message')
            respond activity, model: [user: user], view: 'create'
            return
        }

        activity.save flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'activity.label', default: 'Activity'), activity.id])
                redirect(controller: "activity", action: "index")
            }
            '*' { respond activity, [status: CREATED] }
        }
    }

    @Transactional
    def saveAppointment(Activity activity)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (activity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (activity.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond activity.errors, model: [user: user], view: 'createAppointment'
            return
        }
        def existList = Activity.findAll("from Activity where assignedTo.id = :assignedTo and status in :statusList and :startTime between startTime and endTime", [assignedTo: activity?.assignedTo?.id, statusList: ['未执行', '已推迟'], startTime: activity?.startTime])
        if (existList)
        {
            flash.message = message(code: 'activity.startTime.exist.message')
            respond activity, model: [user: user], view: 'createAppointment'
            return
        }

        activity.save flush: true

        redirect(controller: "activity", action: "index")
    }

    @Transactional
    def saveTask(Activity activity)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (activity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (activity.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond activity.errors, model: [user: user], view: 'createTask'
            return
        }

        def existList = Activity.findAll("from Activity where assignedTo.id = :assignedTo and status in :statusList and :startTime between startTime and endTime", [assignedTo: activity?.assignedTo?.id, statusList: ['未执行', '已推迟'], startTime: activity?.startTime])
        if (existList)
        {
            flash.message = message(code: 'activity.startTime.exist.message')
            respond activity, model: [user: user], view: 'createTask'
            return
        }

        activity.save()
        // flush: true

        def follow = new Follow()
        follow.user = user
        follow.activity = activity
        follow.source = activity?.user
        follow.save()

        redirect(controller: "activity", action: "index")
    }

    def edit(Activity activity)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)
        def permission = false

        TeamRole editTeamRole = TeamRole.findByName('Edit')
        ActivityTeam activityTeam = ActivityTeam.findByActivityAndUser(activity, user)

        if (activity?.user?.id == user?.id || activityTeam?.teamRole?.id == editTeamRole?.id)
        {
            permission = true
        }
        else if (params['teamName'])
        {
            def activityPermission
            switch (params['teamName'])
            {
            case "contactTeam":
                activityPermission = ContactTeam.findByContactAndUser(activity?.contact, user)?.activityPermission
                if (activityPermission?.id == editTeamRole.id)
                {
                    permission = true
                }
                break
            case "accountTeam":
                activityPermission = AccountTeam.findByAccountAndUser(activity?.account, user)?.activityPermission
                if (activityPermission?.id == editTeamRole.id)
                {
                    permission = true
                }
                break
            case "opportunityTeam":
                activityPermission = OpportunityTeam.findByOpportunityAndUser(activity?.opportunity, user)?.activityPermission
                if (activityPermission?.id == editTeamRole.id)
                {
                    permission = true
                }
                break
            case "campaignTeam":
                activityPermission = CampaignTeam.findByCampaignAndUser(activity?.campaign, user)?.activityPermission
                if (activityPermission?.id == editTeamRole.id)
                {
                    permission = true
                }
                break
            case "issueTeam":
                activityPermission = IssueTeam.findByIssueAndUser(activity?.issue, user)?.activityPermission
                if (activityPermission?.id == editTeamRole.id)
                {
                    permission = true
                }
                break
            case "assetTeam":
                activityPermission = AssetTeam.findByAssetAndUser(activity?.asset, user)?.activityPermission
                if (activityPermission?.id == editTeamRole.id)
                {
                    permission = true
                }
                break
            }
        }

        if (permission)
        {
            def displayRating = activity.status == '已完成' && user.id == activity?.user?.id
            respond activity, model: [user: user, displayRating: displayRating]
        }
        else
        {
            flash.message = "没有编辑权限"
            redirect uri: request.getHeader("referer")
            // respond activity, view: 'show'
        }
    }

    @Transactional
    def update(Activity activity)
    {
        def username = springSecurityService?.getPrincipal()?.username
        def user = User.findByUsername(username)

        if (activity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (activity.hasErrors())
        {
            transactionStatus.setRollbackOnly()
            respond activity.errors, model: [user: user], view: 'edit'
            return
        }

        activity.save flush: true
        subscribeService.sendSubscribe activity

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'activity.label',
                                                                                        default: 'Activity'),
                    activity.id])
                redirect activity
                // redirect(controller: "opportunity", action: "show", params: [id: activity.opportunity.id])
            }
            '*' { respond activity, [status: OK] }
        }
    }

    @Transactional
    def delete(Activity activity)
    {

        if (activity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        activity.delete flush: true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'activity.label',
                                                                                        default: 'Activity'),
                    activity.id])
                // redirect action: "index", method: "GET"
                redirect(controller: "opportunity", action: "show", params: [id: activity?.opportunity?.id])

            }
            '*' { render status: NO_CONTENT }
        }
    }

    protected void notFound()
    {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'activity.label',
                                                                                          default: 'Activity'),
                    params.id])
                redirect action: "index", method: "GET"
            }
            '*' { render status: NOT_FOUND }
        }
    }

    @Transactional
    def complete(Activity activity)
    {
        if (activity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (activity?.notes?.size() == 0)
        {
            flash.message = "请录入任务笔记"
            redirect action: "show", id: activity?.id
            return
        }

        if (!activity?.actualStartTime || !activity?.actualEndTime)
        {
            flash.message = "请完善实际开始时间和实际结束时间"
            redirect action: "show", id: activity?.id
            return
        }

        if (activity?.tasks?.size() > 0 && activity.progress != 1)
        {
            flash.message = message(code: 'task.doesnt.finish.message')
            redirect action: "show", id: activity?.id
            return
        }

        activity.status = '已完成'

        activity.save flush: true

        subscribeService.sendSubscribe activity

        redirect(controller: "activity", action: "index")
    }

    @Transactional
    def delay(Activity activity)
    {
        if (activity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        activity.status = '已推迟'

        activity.save flush: true

        redirect(controller: "activity", action: "index")
    }

    @Transactional
    def cancel(Activity activity)
    {
        if (activity == null)
        {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }


        activity.status = '已取消'

        activity.save flush: true

        redirect(controller: "activity", action: "index")
    }

    def taskList(Integer max)
    {
        def username = springSecurityService?.getPrincipal()?.username
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd")
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM")
        Calendar currentDay = Calendar.getInstance()
        Calendar currentWeek = Calendar.getInstance()
        Calendar currentMonth = Calendar.getInstance()
        Calendar currentSeason = Calendar.getInstance()
        Calendar currentYear = Calendar.getInstance()
        Calendar endWeek = Calendar.getInstance()
        Calendar endMonth = Calendar.getInstance()
        Calendar endSeason = Calendar.getInstance()
        Calendar endYear = Calendar.getInstance()
        int season = Math.floor((currentSeason.get(Calendar.MONTH)) / 3)
        currentWeek.set(Calendar.DAY_OF_WEEK, 2)
        currentMonth.set(Calendar.DAY_OF_MONTH, 1)
        currentSeason.set(Calendar.DAY_OF_MONTH, 1)
        currentSeason.set(Calendar.MONTH, 3 * season)
        currentYear.set(Calendar.DAY_OF_YEAR, 1)
        endWeek.set(Calendar.DAY_OF_WEEK, 1)
        endWeek.add(Calendar.DATE, 7)
        endMonth.set(Calendar.DAY_OF_MONTH, 1)
        endMonth.add(Calendar.MONTH, 1)
        endSeason.set(Calendar.DAY_OF_MONTH, 1)
        if (season == 4)
        {
            endSeason.set(Calendar.MONTH, 0)
            endSeason.add(Calendar.YEAR, 1)
        }
        else
        {
            endSeason.set(Calendar.MONTH, 3 * season)
        }
        endYear.set(Calendar.DAY_OF_YEAR, 1)
        endYear.add(Calendar.YEAR, 1)
        String cDay = sdf.format(currentDay.getTime())
        String cWeek = sdf.format(currentWeek.getTime())
        String cMonth = sdf.format(currentMonth.getTime())
        String cSeason = sdf.format(currentSeason.getTime())
        String cYear = sdf.format(currentYear.getTime())
        String eWeek = sdf.format(endWeek.getTime())
        String eMonth = sdf.format(endMonth.getTime())
        String eSeason = sdf.format(endSeason.getTime())
        String eYear = sdf.format(endYear.getTime())
        def amount = []

        def time
        def name = params['name']
        def status = ""
        if (name == '本日已完成任务' || name == '本日未完成任务')
        {
            time = currentDay.getTime()
            if (name == '本日已完成预约')
            {
                status = "已完成"
            }
        }

        if (name == '本周已完成任务' || name == '本周未完成任务')
        {
            time = currentWeek.getTime()
            if (name == '本周已完成任务')
            {
                status = "已完成"
            }
        }

        if (name == '本月已完成任务' || name == '本月未完成任务')
        {
            time = currentMonth.getTime()
            if (name == '本月已完成任务')
            {
                status = "已完成"
            }
        }

        if (name == '本季已完成任务' || name == '本季未完成任务')
        {
            time = currentSeason.getTime()
            if (name == '本季已完成任务')
            {
                status = "已完成"
            }
        }

        if (name == '本年已完成任务' || name == '本年未完成任务')
        {
            time = currentYear.getTime()
            if (name == '本年已完成任务')
            {
                status = "已完成"
            }
        }

        def activityList = []
        def count
        if (status == "已完成")
        {
            activityList = Activity.findAll("from Activity where startTime>='${time}' and user.username = '${username}' and type.name = 'Task' and status = '已完成'", [max: params.max ?: 10, offset: params.offset ?: 0])
            count = Activity.executeQuery("select count(id) from Activity where startTime>='${time}' and user.username = '${username}' and type.name = 'Task' and status = '已完成'")
        }
        else
        {
            activityList = Activity.findAll("from Activity where startTime>='${time}' and user.username = '${username}' and type.name = 'Task' and status <> '已完成'", [max: params.max ?: 10, offset: params.offset ?: 0])
            count = Activity.executeQuery("select count(id) from Activity where startTime>='${time}' and user.username = '${username}' and type.name = 'Task' and status <> '已完成'")
        }

        respond activityList, model: [activityCount: count[0]]
    }

    def appointmentList()
    {
        def username = springSecurityService?.getPrincipal()?.username
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd")
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM")
        Calendar currentDay = Calendar.getInstance()
        Calendar currentWeek = Calendar.getInstance()
        Calendar currentMonth = Calendar.getInstance()
        Calendar currentSeason = Calendar.getInstance()
        Calendar currentYear = Calendar.getInstance()
        Calendar endWeek = Calendar.getInstance()
        Calendar endMonth = Calendar.getInstance()
        Calendar endSeason = Calendar.getInstance()
        Calendar endYear = Calendar.getInstance()
        int season = Math.floor((currentSeason.get(Calendar.MONTH)) / 3)
        currentWeek.set(Calendar.DAY_OF_WEEK, 2)
        currentMonth.set(Calendar.DAY_OF_MONTH, 1)
        currentSeason.set(Calendar.DAY_OF_MONTH, 1)
        currentSeason.set(Calendar.MONTH, 3 * season)
        currentYear.set(Calendar.DAY_OF_YEAR, 1)
        endWeek.set(Calendar.DAY_OF_WEEK, 1)
        endWeek.add(Calendar.DATE, 7)
        endMonth.set(Calendar.DAY_OF_MONTH, 1)
        endMonth.add(Calendar.MONTH, 1)
        endSeason.set(Calendar.DAY_OF_MONTH, 1)
        if (season == 4)
        {
            endSeason.set(Calendar.MONTH, 0)
            endSeason.add(Calendar.YEAR, 1)
        }
        else
        {
            endSeason.set(Calendar.MONTH, 3 * season)
        }
        endYear.set(Calendar.DAY_OF_YEAR, 1)
        endYear.add(Calendar.YEAR, 1)
        String cDay = sdf.format(currentDay.getTime())
        String cWeek = sdf.format(currentWeek.getTime())
        String cMonth = sdf.format(currentMonth.getTime())
        String cSeason = sdf.format(currentSeason.getTime())
        String cYear = sdf.format(currentYear.getTime())
        String eWeek = sdf.format(endWeek.getTime())
        String eMonth = sdf.format(endMonth.getTime())
        String eSeason = sdf.format(endSeason.getTime())
        String eYear = sdf.format(endYear.getTime())
        def amount = []

        def time
        def name = params['name']
        def status = ""
        if (name == '本日已完成预约' || name == '本日未完成预约')
        {
            time = currentDay.getTime()
            if (name == '本日已完成预约')
            {
                status = "已完成"
            }
        }

        if (name == '本周已完成预约' || name == '本周未完成预约')
        {
            time = currentWeek.getTime()
            if (name == '本周已完成预约')
            {
                status = "已完成"
            }
        }

        if (name == '本月已完成预约' || name == '本月未完成预约')
        {
            time = currentMonth.getTime()
            if (name == '本月已完成预约')
            {
                status = "已完成"
            }
        }

        if (name == '本季已完成预约' || name == '本季未完成预约')
        {
            time = currentSeason.getTime()
            if (name == '本季已完成预约')
            {
                status = "已完成"
            }
        }

        if (name == '本年已完成预约' || name == '本年未完成预约')
        {
            time = currentYear.getTime()
            if (name == '本年已完成预约')
            {
                status = "已完成"
            }
        }

        def activityList = []
        def count
        if (status == "已完成")
        {
            activityList = Activity.findAll("from Activity where startTime>='${time}' and user.username = '${username}' and type.name = 'Appointment' and status = '已完成'", [max: params.max ?: 10, offset: params.offset ?: 0])
            count = Activity.executeQuery("select count(id) from Activity where startTime>='${time}' and user.username = '${username}' and type.name = 'Appointment' and status = '已完成'")
        }
        else
        {
            activityList = Activity.findAll("from Activity where startTime>='${time}' and user.username = '${username}' and type.name = 'Appointment' and status <> '已完成'", [max: params.max ?: 10, offset: params.offset ?: 0])
            count = Activity.executeQuery("select count(id) from Activity where startTime>='${time}' and user.username = '${username}' and type.name = 'Appointment' and status <> '已完成'")
        }

        respond activityList, model: [activityCount: count[0]]
    }

    def searchActivity()
    {
        def username = springSecurityService?.getPrincipal()?.username
        def department = params["department"]
        def owner = params["owner"]
        def status = params["status"]
        String sql = "from Activity as u where 1=1"
        if (!UserRole.findByUserAndRole(User.findByUsername(username), Role.findByAuthority('ROLE_ADMINISTRATOR')) && !UserRole.findByUserAndRole(User.findByUsername(username), Role.findByAuthority('ROLE_COMPANY_ADMINISTRATOR')))
        {
            sql += " and u.user.username='${username}'"
        }
        else
        {
            if (department)
            {
                sql += " and u.user.department.name like '%${department}%'"
            }
            if (owner)
            {
                sql += " and u.user.fullName like '%${owner}%'"
            }
        }

        if (status)
        {
            sql += " and u.status like '%${status}%'"
        }
        def startTime = params["startTime"]
        if (startTime)
        {
            sql += " and u.createdDate > '${startTime}'"
        }
        def endTime = params["endTime"]
        if (endTime)
        {
            sql += " and u.createdDate < '${endTime}'"
        }

        String countSql = "select count(u.id) " + sql
        sql += ' order by modifiedDate desc'

        def activityList = Activity.findAll(sql, [max: params.max ?: 10, offset: params.offset ?: 0])
        def count = Activity.executeQuery(countSql)

        respond activityList, model: [activityCount: count[0], params: params], view: 'administrator'
    }
}
